package com.example.android.jmatt.acc;

import java.io.IOException;
import java.io.InputStream;

import android.os.AsyncTask;
import android.os.SystemClock;

/**
 * Only accepts a single InputStream, will throw a RuntimeException is more than one is
 * supplied.
 * @author jmatt
 *
 */
public class FileReaderTask extends AsyncTask<Job, Integer, Job> {

    private Job mJob;
    private ProgressListener mListener;
    
    public FileReaderTask(ProgressListener onProgress) {
        mListener = onProgress;
    }
    
    /**
     * 
     */
    @Override
    protected Job doInBackground(Job... params) {
        if (params.length > 1) {
            throw new RuntimeException("Only one InputStream per task is allowed.");
        }
        
        mJob = params[0];
        
        return readInput();
    }
    
    private Job readInput() {
        // TODO how could we make this more efficient?
        byte[] allBytes = new byte[0];
        int bytesRead = -1;
        int totalBytes = 0;

        byte[] buffer = new byte[10 * 1024];
        do {
            try {
                bytesRead = mJob.stream.read(buffer);
                if (bytesRead != -1) {
                    byte[] previousBytes = allBytes;
                    allBytes = new byte[bytesRead + totalBytes];
                    System.arraycopy(previousBytes, 0, allBytes, 0, previousBytes.length);
                    System.arraycopy(buffer, 0, allBytes, totalBytes, bytesRead);
                    
                    totalBytes += bytesRead;
                }
                publishProgress(totalBytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            // Log.d("JMATT", "Read " + bytesRead + " bytes out of a possible " + data.length);
        } while (bytesRead != -1);
        mJob.bytes = allBytes;
        return mJob;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        mListener.onProgress(values[0]);
    }
    
    
    
    @Override
    protected void onPostExecute(Job job) {
        mJob.finishTime = SystemClock.uptimeMillis();
        mListener.onFinished(mJob);
    }



    public interface ProgressListener {
        public void onProgress(Integer progress);
        public void onFinished(Job job);
    }

}
